#include "esp_log.h"
#include "driver/gpio.h"
#include "driver/i2s_std.h"
#include "freertos/FreeRTOS.h"
#include <math.h>
#include "data_music.h"

#define I2S_BCK GPIO_NUM_27
#define I2S_WS GPIO_NUM_25
#define I2S_DOUT GPIO_NUM_26

#define PCM_XSMT GPIO_NUM_32
#define PCM_FMT GPIO_NUM_33
#define PCM_FLT GPIO_NUM_12
#define PCM_DEMP GPIO_NUM_13
#define GF_8002A_SD GPIO_NUM_23

#define SAMPLE_RATE 44100
#define FREQ 440

#define BUFFER_SIZE 1024

// 生成正弦波
void generate_wave(float freq, int16_t *buffer, size_t samples);
// 播放音符
void play_note(i2s_chan_handle_t tx_handle, float freq, int duration_ms);
// 播放音乐
void play_music(i2s_chan_handle_t tx_handle, uint8_t index);

void app_main(void)
{

    esp_err_t ret;

    gpio_set_direction(PCM_XSMT, GPIO_MODE_OUTPUT);
    gpio_set_direction(PCM_FMT, GPIO_MODE_OUTPUT);
    gpio_set_direction(PCM_FLT, GPIO_MODE_OUTPUT);
    gpio_set_direction(PCM_DEMP, GPIO_MODE_OUTPUT);
    gpio_set_direction(GF_8002A_SD, GPIO_MODE_OUTPUT);

    gpio_set_level(PCM_XSMT, 1);
    gpio_set_level(PCM_FMT, 0);
    gpio_set_level(PCM_FLT, 0);
    gpio_set_level(PCM_DEMP, 0);
    gpio_set_level(GF_8002A_SD, 0);

    vTaskDelay(pdMS_TO_TICKS(100));

    i2s_chan_config_t chan_cfg = I2S_CHANNEL_DEFAULT_CONFIG(I2S_NUM_0, I2S_ROLE_MASTER);
    i2s_chan_handle_t tx_handle;

    ret = i2s_new_channel(&chan_cfg, &tx_handle, NULL);
    if (ret == ESP_OK)
    {
        ESP_LOGI("I2S_INIT", "I2S initialized successfully");
    }
    else
    {
        ESP_LOGE("I2S_INIT", "Failed to initialize I2S: %s", esp_err_to_name(ret));
    }
    i2s_std_config_t std_config = {
        .clk_cfg = I2S_STD_CLK_DEFAULT_CONFIG(44100),
        .slot_cfg = I2S_STD_PHILIPS_SLOT_DEFAULT_CONFIG(I2S_DATA_BIT_WIDTH_16BIT, I2S_SLOT_MODE_STEREO),
        .gpio_cfg = {
            .mclk = I2S_GPIO_UNUSED,
            .bclk = I2S_BCK,
            .ws = I2S_WS,
            .din = I2S_GPIO_UNUSED,
            .dout = I2S_DOUT,
            .invert_flags = {
                .bclk_inv = false,
                .ws_inv = false,
                .mclk_inv = false}},
    };
    ret = i2s_channel_init_std_mode(tx_handle, &std_config);
    if (ret == ESP_OK)
    {
        ESP_LOGI("I2S_INIT", "I2S std mode initialized successfully");
    }
    else
    {
        ESP_LOGE("I2S_INIT", "Failed to initialize I2S: %s", esp_err_to_name(ret));
    }

    ret = i2s_channel_enable(tx_handle);
    if (ret == ESP_OK)
    {
        ESP_LOGI("I2S_INIT", "I2S enabled successfully");
    }
    else
    {
        ESP_LOGE("I2S_INIT", "Failed to enable I2S: %s", esp_err_to_name(ret));
    }

    // 创建16位音频缓冲区
    int16_t audio_buffer[128];
    for (int i = 0; i < 128; i++)
    {
        audio_buffer[i] = (int16_t)(32767 * sin(2 * M_PI * FREQ * i / SAMPLE_RATE) * 10 / 1000);
    }

    uint8_t mIndex = 0;
    while (1)
    {

        if (mIndex >= NUM_SONGS)
        {
            mIndex = 0;
        }
        

        gpio_set_level(GF_8002A_SD, 0);
        play_music(tx_handle, mIndex);
        gpio_set_level(GF_8002A_SD, 1);

        mIndex++;

        // 短暂延时
        vTaskDelay(pdMS_TO_TICKS(1000));
    }
}

void generate_wave(float freq, int16_t *buffer, size_t samples)
{
    for (int i = 0; i < samples; i++)
    {
        buffer[i] = (int16_t)(32767 * 0.1 * sin(2 * M_PI * freq * i / SAMPLE_RATE));
    }
}

void play_note(i2s_chan_handle_t tx_handle, float freq, int duration_ms)
{
    int16_t buffer[BUFFER_SIZE];
    int cycles = duration_ms * SAMPLE_RATE / 1000 / BUFFER_SIZE;

    generate_wave(freq, buffer, BUFFER_SIZE);
    for (int i = 0; i < cycles; i++)
    {
        size_t bytes_written;
        i2s_channel_write(tx_handle, buffer, BUFFER_SIZE * 2, &bytes_written, portMAX_DELAY);
    }
}

void play_little_star(i2s_chan_handle_t tx_handle)
{
    // 小星星主旋律
    float melody[] = {NOTE_C4, NOTE_C4, NOTE_G4, NOTE_G4, NOTE_A4, NOTE_A4, NOTE_G4,
                      NOTE_F4, NOTE_F4, NOTE_E4, NOTE_E4, NOTE_D4, NOTE_D4, NOTE_C4};
    int durations[] = {400, 400, 400, 400, 400, 400, 800, 400, 400, 400, 400, 400, 400, 800};

    for (int i = 0; i < 14; i++)
    {
        play_note(tx_handle, melody[i], durations[i]);
        vTaskDelay(pdMS_TO_TICKS(50)); // 音符间间隔
    }
}

void play_music(i2s_chan_handle_t tx_handle, uint8_t index)
{

    Song song = songs[index];
    Note *notes = song.notes;

    if (index >= NUM_SONGS)
    {
        index = 0;
    }
    

    for (int i = 0; i < song.noteCount; i++)
    {
        play_note(tx_handle, notes[i].frequency, notes[i].duration);
        vTaskDelay(pdMS_TO_TICKS(50)); // 音符间间隔
    }
}

